package kuzmenkov.oip.adapters.sun.jai;

import kuzmenkov.oip.adapters.ImageProcessingAdapter;
import kuzmenkov.oip.common.FileTool;

import javax.media.jai.JAI;
import javax.media.jai.KernelJAI;
import javax.media.jai.RenderedOp;
import java.net.URL;
import java.util.logging.Logger;

/**
 * The class adapts JAI Edge Detection
 * User: Michael Kuzmenkov
 * Date: 26.03.2009
 * Time: 1:32:53
 */
public class EdgeDetectionAdapter extends ImageProcessingAdapter {
    private static final Logger log = Logger.getLogger(EdgeDetectionAdapter.class.getName());


    /**
     * It takes three parameters. The first parameter is a path to an image (String).
     * The second parameter is a gradient mask (Integer). The third parameter is
     * the orthogonal gradient mask (Integer).
     * It returns two results. These are the path to the output image (String)
     * and duration of the processing
     * <p/>
     * The first mask can be:
     * 0 (GRADIENT_MASK_SOBEL_HORIZONTAL) - the horizontal Sobel's mask. The default.
     * 1 - the Robert's horizontal mask
     * 2 - the Frei and Chen's horizontal mask
     * The second mask can be:
     * 0 (GRADIENT_MASK_SOBEL_VERTICAL) - the vertical Sobel's mask.
     * 1 - the Robert's vertical mask
     * 2 - the Frei and Chen's vertical mask
     *
     * @param params the input parameters
     * @return the path to the output image and duration of processing
     */
    public Object[] process(Object[] params) throws Exception {
        
        String path = (String) params[0];
        Integer mask1 = (Integer) params[1];
        Integer mask2 = (Integer) params[2];
        log.info("path=" + path + ", mask1=" + mask1 + ", mask2=" + mask2);

                FileTool ftool = FileTool.getInstance();
        path = ftool.relPathToAbs(path);
        log.info("modified path="+path);
        RenderedOp srcImage = JAI.create("fileload", path);
        log.info("srcImage=" + srcImage);

        KernelJAI m1 = null;
        int num1 = mask1.intValue();
        switch (num1) {
            case 0:
                m1 = KernelJAI.GRADIENT_MASK_SOBEL_HORIZONTAL;
                break;
            case 1:
                float[] roberts_h_data = {
                        0.0F, 0.0F, -1.0F,
                        0.0F, 1.0F, 0.0F,
                        0.0F, 0.0F, 0.0F};
                m1 = new KernelJAI(3, 3, roberts_h_data);
                break;
            case 2:
                float[] freichen_h_data = {
                        1.0F, 0.0F, -1.0F,
                        1.414F, 0.0F, -1.414F,
                        1.0F, 0.0F, -1.0F};
                m1 = new KernelJAI(3, 3, freichen_h_data);
            default:
                log.warning("The gradient mask 1 is wrong. The Sobel's mask will be used");
                m1 = KernelJAI.GRADIENT_MASK_SOBEL_HORIZONTAL;
        }

        KernelJAI m2 = null;
        int num2 = mask2.intValue();
        switch (num2) {
            case 0:
                m2 = KernelJAI.GRADIENT_MASK_SOBEL_VERTICAL;
                break;
            case 1:
                float[] roberts_v_data = {
                        -1.0F, 0.0F, 0.0F,
                        0.0F, 1.0F, 0.0F,
                        0.0F, 0.0F, 0.0F};
                m2 = new KernelJAI(3, 3, roberts_v_data);
                break;
            case 2:
                float[] freichen_v_data = {
                        -1.0F, -1.414F, -1.0F,
                        0.0F, 0.0F, 0.0F,
                        1.0F, 1.414F, 1.0F};
                m2 = new KernelJAI(3, 3, freichen_v_data);
            default:
                log.warning("The gradient mask 2 is wrong. The Sobel's mask will be used");
                m2 = KernelJAI.GRADIENT_MASK_SOBEL_VERTICAL;


        }


        Long duration = System.nanoTime();
        RenderedOp dstImage = JAI.create("gradientmagnitude", srcImage, m1, m2);
        duration = System.nanoTime() - duration;

        String dstFileName = "1.png";
        String dstPath = ftool.getTempDir(getSessionId())+dstFileName;
        log.info("destination path="+dstPath);
        JAI.create("filestore", dstImage, dstPath, "PNG", null);

        String relDstPath = ftool.getRelativeTempDir(getSessionId())+dstFileName;
        log.info("relative destination path="+relDstPath);
        

        Integer dur = new Integer(duration.intValue());
        return new Object[]{relDstPath, dur};
    }
}